"""
语法分析器 V3.0
完全重新设计，构建完整的AST
"""

import ply.yacc as yacc
try:
    from .lexer_v3 import LexerV3
except ImportError:
    from lexer_v3 import LexerV3
from typing import Dict, Any, List, Optional

class ParserV3:
    """语法分析器 V3.0"""
    
    # PLY要求tokens作为类属性
    tokens = [
        # 标识符和字面量
        'IDENTIFIER', 'STRING_LITERAL', 'NUMBER_LITERAL', 'BOOLEAN_LITERAL',
        
        # 操作符
        'PLUS', 'MINUS', 'MULTIPLY', 'DIVIDE', 'MODULO',
        'EQUALS', 'NOT_EQUALS', 'LESS_THAN', 'LESS_EQUAL', 'GREATER_THAN', 'GREATER_EQUAL',
        'ASSIGN',
        
        # 分隔符
        'COMMA', 'SEMICOLON', 'DOT', 'LPAREN', 'RPAREN',
        'LBRACKET', 'RBRACKET', 'LBRACE', 'RBRACE',
        
        # 其他
        'QUESTION_MARK',
        
        # SQL关键字
        'CREATE', 'TABLE', 'DROP', 'ALTER', 'INDEX',
        'SELECT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'SET', 'DELETE', 'FROM', 'WHERE',
        'ORDER', 'BY', 'GROUP', 'HAVING', 'DISTINCT', 'AS', 'ASC', 'DESC',
        'INT', 'INTEGER', 'VARCHAR', 'CHAR', 'FLOAT', 'DOUBLE', 'BOOLEAN', 'BOOL',
        'DATE', 'TIME', 'DATETIME',
        'PRIMARY', 'KEY', 'FOREIGN', 'REFERENCES', 'UNIQUE', 'NOT', 'NULL', 'DEFAULT', 'AUTO_INCREMENT',
        'AND', 'OR', 'IN', 'EXISTS', 'BETWEEN', 'LIKE', 'IS',
        'COUNT', 'SUM', 'AVG', 'MIN', 'MAX',
        'ALL', 'ANY', 'SOME', 'CASE', 'WHEN', 'THEN', 'ELSE', 'END', 'LIMIT', 'OFFSET',
        
        # 复杂查询相关token
        'JOIN', 'INNER', 'OUTER', 'LEFT', 'RIGHT', 'FULL', 'ON',
        'UNION', 'INTERSECT', 'EXCEPT', 'WITH', 'RECURSIVE',
        'PARTITION', 'OVER', 'WINDOW', 'ROWS', 'RANGE',
        'PRECEDING', 'FOLLOWING', 'CURRENT', 'ROW', 'UNBOUNDED',
        'FILTER', 'WITHIN'
    ]
    
    def __init__(self):
        """初始化语法分析器"""
        self.lexer = LexerV3()
        self.parser = None
        self.errors = []
        self._build_parser()
    
    def _build_parser(self):
        """构建语法分析器"""
        self.parser = yacc.yacc(module=self, debug=False, write_tables=False)
    
    def parse(self, text: str) -> Optional[Dict[str, Any]]:
        """解析SQL语句"""
        self.errors = []
        try:
            result = self.parser.parse(text, lexer=self.lexer.lexer)
            # 如果结果是列表，取第一个语句
            if isinstance(result, list) and len(result) > 0:
                return result[0]
            elif isinstance(result, dict):
                return result
            else:
                return None
        except Exception as e:
            self.errors.append(f"语法分析错误: {str(e)}")
            return None
    
    # 语法规则
    def p_statement_list(self, p):
        """statement_list : statement_list statement
                          | statement"""
        if len(p) == 3:
            p[0] = p[1] + [p[2]]
        else:
            p[0] = [p[1]]
    
    def p_statement(self, p):
        """statement : create_table_statement SEMICOLON
                     | insert_statement SEMICOLON
                     | select_statement SEMICOLON
                     | delete_statement SEMICOLON
                     | update_statement SEMICOLON
                     | drop_table_statement SEMICOLON"""
        p[0] = p[1]
    
    # CREATE TABLE 语句
    def p_create_table_statement(self, p):
        """create_table_statement : CREATE TABLE IDENTIFIER LPAREN column_list RPAREN"""
        p[0] = {
            'type': 'CREATE_TABLE',
            'table_name': p[3],
            'columns': p[5],
            'line': p.lineno(1)
        }
    
    def p_column_list(self, p):
        """column_list : column_list COMMA column_definition
                       | column_definition"""
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        else:
            p[0] = [p[1]]
    
    def p_column_definition(self, p):
        """column_definition : IDENTIFIER data_type
                             | IDENTIFIER data_type column_constraints"""
        column_def = {
            'name': p[1],
            'type': p[2],
            'constraints': []
        }
        
        if len(p) == 4:
            column_def['constraints'] = p[3]
        
        p[0] = column_def
    
    def p_data_type(self, p):
        """data_type : INT
                     | INTEGER
                     | VARCHAR LPAREN NUMBER_LITERAL RPAREN
                     | CHAR LPAREN NUMBER_LITERAL RPAREN
                     | FLOAT
                     | DOUBLE
                     | BOOLEAN
                     | BOOL
                     | DATE
                     | TIME
                     | DATETIME"""
        if len(p) == 2:
            p[0] = {'type': p[1].lower()}
        else:
            p[0] = {'type': p[1].lower(), 'length': p[3]}
    
    def p_column_constraints(self, p):
        """column_constraints : column_constraints column_constraint
                              | column_constraint"""
        if len(p) == 3:
            p[0] = p[1] + [p[2]]
        else:
            p[0] = [p[1]]
    
    def p_column_constraint(self, p):
        """column_constraint : PRIMARY KEY
                             | NOT NULL
                             | UNIQUE
                             | DEFAULT literal"""
        if len(p) == 3:
            if p[1] == 'PRIMARY':
                p[0] = {'type': 'PRIMARY_KEY'}
            elif p[1] == 'NOT':
                p[0] = {'type': 'NOT_NULL'}
            else:
                p[0] = {'type': p[1]}
        else:
            p[0] = {'type': 'DEFAULT', 'value': p[3]}
    
    # INSERT 语句
    def p_insert_statement(self, p):
        """insert_statement : INSERT INTO IDENTIFIER VALUES LPAREN value_list RPAREN
                            | INSERT INTO IDENTIFIER LPAREN column_list RPAREN VALUES LPAREN value_list RPAREN"""
        if len(p) == 8:
            # INSERT INTO table VALUES (values)
            p[0] = {
                'type': 'INSERT',
                'table_name': p[3],
                'columns': None,
                'values': p[6],
                'line': p.lineno(1)
            }
        else:
            # INSERT INTO table (columns) VALUES (values)
            p[0] = {
                'type': 'INSERT',
                'table_name': p[3],
                'columns': [col['name'] for col in p[5]],
                'values': p[9],
                'line': p.lineno(1)
            }
    
    def p_value_list(self, p):
        """value_list : value_list COMMA literal
                      | literal"""
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        else:
            p[0] = [p[1]]
    
    def p_literal(self, p):
        """literal : STRING_LITERAL
                   | NUMBER_LITERAL
                   | BOOLEAN_LITERAL
                   | NULL"""
        if p[1] is None:
            p[0] = {'type': 'NULL', 'value': None}
        elif isinstance(p[1], str):
            p[0] = {'type': 'STRING', 'value': p[1]}
        elif isinstance(p[1], (int, float)):
            p[0] = {'type': 'NUMBER', 'value': p[1]}
        elif isinstance(p[1], bool):
            p[0] = {'type': 'BOOLEAN', 'value': p[1]}
        else:
            p[0] = {'type': 'UNKNOWN', 'value': p[1]}
    
    # SELECT 语句
    def p_select_statement(self, p):
        """select_statement : SELECT select_list FROM IDENTIFIER
                            | SELECT select_list FROM IDENTIFIER WHERE condition
                            | SELECT select_list FROM IDENTIFIER GROUP BY grouping_columns
                            | SELECT select_list FROM IDENTIFIER GROUP BY grouping_columns HAVING condition
                            | SELECT select_list FROM IDENTIFIER WHERE condition GROUP BY grouping_columns
                            | SELECT select_list FROM IDENTIFIER WHERE condition GROUP BY grouping_columns HAVING condition
                            | SELECT select_list FROM IDENTIFIER ORDER BY order_columns
                            | SELECT select_list FROM IDENTIFIER WHERE condition ORDER BY order_columns
                            | SELECT select_list FROM IDENTIFIER LIMIT NUMBER_LITERAL
                            | SELECT select_list FROM IDENTIFIER WHERE condition LIMIT NUMBER_LITERAL
                            | SELECT select_list FROM IDENTIFIER LIMIT NUMBER_LITERAL OFFSET NUMBER_LITERAL
                            | SELECT select_list FROM IDENTIFIER WHERE condition LIMIT NUMBER_LITERAL OFFSET NUMBER_LITERAL"""
        select_stmt = {
            'type': 'SELECT',
            'columns': p[2],
            'table_name': p[4],
            'where_clause': None,
            'group_by': None,
            'having': None,
            'order_by': None,
            'limit': None,
            'offset': None,
            'line': p.lineno(1)
        }
        
        # 处理不同长度的规则
        if len(p) == 7:  # SELECT select_list FROM IDENTIFIER WHERE condition 或 GROUP BY 或 ORDER BY 或 LIMIT
            if p[5] == 'WHERE':
                select_stmt['where_clause'] = p[6]
            elif p[5] == 'GROUP':
                select_stmt['group_by'] = p[7]
            elif p[5] == 'ORDER':
                select_stmt['order_by'] = p[7]
            elif p[5] == 'LIMIT':
                select_stmt['limit'] = int(p[6])
        elif len(p) == 9:  # WHERE condition GROUP BY 或 GROUP BY HAVING 或 WHERE condition ORDER BY 或 LIMIT OFFSET
            if p[5] == 'WHERE' and p[7] == 'GROUP':
                select_stmt['where_clause'] = p[6]
                select_stmt['group_by'] = p[9]
            elif p[5] == 'GROUP' and p[7] == 'HAVING':
                select_stmt['group_by'] = p[7]
                select_stmt['having'] = p[9]
            elif p[5] == 'WHERE' and p[7] == 'ORDER':
                select_stmt['where_clause'] = p[6]
                select_stmt['order_by'] = p[9]
            elif p[5] == 'LIMIT' and p[7] == 'OFFSET':
                select_stmt['limit'] = int(p[6])
                select_stmt['offset'] = int(p[8])
        elif len(p) == 11:  # WHERE condition GROUP BY HAVING 或 WHERE condition LIMIT OFFSET
            if p[5] == 'WHERE' and p[7] == 'GROUP' and p[9] == 'HAVING':
                select_stmt['where_clause'] = p[6]
                select_stmt['group_by'] = p[9]
                select_stmt['having'] = p[11]
            elif p[5] == 'WHERE' and p[7] == 'LIMIT' and p[9] == 'OFFSET':
                select_stmt['where_clause'] = p[6]
                select_stmt['limit'] = int(p[8])
                select_stmt['offset'] = int(p[10])
        
        p[0] = select_stmt

    def p_select_statement_complex(self, p):
        """select_statement : SELECT select_list FROM table_references
                            | SELECT select_list FROM table_references WHERE condition
                            | SELECT select_list FROM table_references WHERE condition GROUP BY grouping_columns
                            | SELECT select_list FROM table_references WHERE condition GROUP BY grouping_columns HAVING condition
                            | SELECT select_list FROM table_references WHERE condition GROUP BY grouping_columns HAVING condition ORDER BY order_columns
                            | SELECT select_list FROM table_references WHERE condition GROUP BY grouping_columns HAVING condition ORDER BY order_columns LIMIT NUMBER_LITERAL
                            | SELECT select_list FROM table_references WHERE condition GROUP BY grouping_columns HAVING condition ORDER BY order_columns LIMIT NUMBER_LITERAL OFFSET NUMBER_LITERAL
                            | SELECT DISTINCT select_list FROM table_references
                            | SELECT select_list FROM table_references JOIN table_references ON condition
                            | SELECT select_list FROM table_references LEFT JOIN table_references ON condition
                            | SELECT select_list FROM table_references RIGHT JOIN table_references ON condition
                            | SELECT select_list FROM table_references FULL JOIN table_references ON condition
                            | SELECT select_list FROM table_references INNER JOIN table_references ON condition
                            | SELECT select_list FROM table_references OUTER JOIN table_references ON condition
                            | select_statement UNION select_statement
                            | select_statement UNION ALL select_statement
                            | select_statement INTERSECT select_statement
                            | select_statement EXCEPT select_statement
                            | WITH cte_list select_statement"""
        # 这里需要根据不同的情况构建不同的AST结构
        # 简化示例，实际实现需要更详细的处理
        if len(p) == 4:
            if p[1] == 'WITH':
                p[0] = {
                    'type': 'SELECT_WITH_CTE',
                    'cte_list': p[2],
                    'select': p[3],
                    'line': p.lineno(1)
                }
            else:
                p[0] = {
                    'type': 'SELECT',
                    'columns': p[2],
                    'from_clause': p[4],
                    'line': p.lineno(1)
                }
        elif len(p) == 6:
            if p[3] == 'UNION':
                p[0] = {
                    'type': 'SET_OPERATION',
                    'operation': 'UNION',
                    'left': p[1],
                    'right': p[5],
                    'line': p.lineno(1)
                }
            else:
                p[0] = {
                    'type': 'SELECT',
                    'columns': p[2],
                    'from_clause': p[4],
                    'where_clause': p[6],
                    'line': p.lineno(1)
                }
        # 处理其他情况...

    def p_table_references(self, p):
        """table_references : table_reference
                            | table_references COMMA table_reference
                            | table_references JOIN table_reference ON condition
                            | table_references LEFT JOIN table_reference ON condition
                            | table_references RIGHT JOIN table_reference ON condition
                            | table_references FULL JOIN table_reference ON condition
                            | table_references INNER JOIN table_reference ON condition
                            | table_references OUTER JOIN table_reference ON condition"""
        if len(p) == 2:
            p[0] = [p[1]]
        elif len(p) == 4:
            p[0] = p[1] + [p[3]]
        elif len(p) == 6:
            join_type = 'INNER' if p[2] == 'JOIN' else p[2]
            p[0] = p[1] + [{
                'type': 'JOIN',
                'join_type': join_type,
                'table': p[3],
                'condition': p[5]
            }]

    def p_table_reference(self, p):
        """table_reference : IDENTIFIER
                        | IDENTIFIER AS IDENTIFIER
                        | LPAREN select_statement RPAREN
                        | LPAREN select_statement RPAREN AS IDENTIFIER"""
        if len(p) == 2:
            p[0] = {'type': 'TABLE', 'name': p[1]}
        elif len(p) == 4:
            if p[1] == '(':
                p[0] = {'type': 'SUBQUERY', 'query': p[2]}
            else:
                p[0] = {'type': 'TABLE', 'name': p[1], 'alias': p[3]}
        elif len(p) == 6:
            p[0] = {'type': 'SUBQUERY', 'query': p[2], 'alias': p[5]}

    def p_cte_list(self, p):
        """cte_list : cte
                    | cte_list COMMA cte"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_cte(self, p):
        """cte : IDENTIFIER AS LPAREN select_statement RPAREN"""
        p[0] = {
            'name': p[1],
            'query': p[4]
        }

    def p_grouping_columns(self, p):
        """grouping_columns : grouping_columns COMMA grouping_column
                            | grouping_column"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_grouping_column(self, p):
        """grouping_column : IDENTIFIER
                        | NUMBER_LITERAL"""
        p[0] = p[1]

    def p_order_columns(self, p):
        """order_columns : order_columns COMMA order_column
                        | order_column"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_order_column(self, p):
        """order_column : IDENTIFIER
                        | IDENTIFIER ASC
                        | IDENTIFIER DESC
                        | NUMBER_LITERAL
                        | NUMBER_LITERAL ASC
                        | NUMBER_LITERAL DESC"""
        if len(p) == 2:
            p[0] = {'column': p[1], 'direction': 'ASC'}
        else:
            p[0] = {'column': p[1], 'direction': p[2]}

    # 扩展select_list以支持表达式和函数调用
    def p_select_list(self, p):
        """select_list : MULTIPLY
                    | select_columns
                    | select_columns COMMA MULTIPLY"""
        if p[1] == '*':
            p[0] = {'type': 'ALL_COLUMNS'}
        elif len(p) == 4:
            p[0] = p[1] + [{'type': 'ALL_COLUMNS'}]
        else:
            p[0] = p[1]

    def p_select_columns(self, p):
        """select_columns : select_columns COMMA select_column
                        | select_column"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_select_column(self, p):
        """select_column : expression
                        | expression AS IDENTIFIER
                        | aggregate_function
                        | aggregate_function AS IDENTIFIER"""
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = {'expression': p[1], 'alias': p[3]}

    def p_aggregate_function(self, p):
        """aggregate_function : COUNT LPAREN MULTIPLY RPAREN
                            | COUNT LPAREN expression RPAREN
                            | SUM LPAREN expression RPAREN
                            | AVG LPAREN expression RPAREN
                            | MIN LPAREN expression RPAREN
                            | MAX LPAREN expression RPAREN
                            | COUNT LPAREN DISTINCT expression RPAREN
                            | SUM LPAREN DISTINCT expression RPAREN
                            | AVG LPAREN DISTINCT expression RPAREN"""
        if len(p) == 5:
            if p[3] == '*':
                p[0] = {'type': 'AGGREGATE', 'function': p[1], 'argument': '*'}
            else:
                p[0] = {'type': 'AGGREGATE', 'function': p[1], 'argument': p[3]}
        else:
            p[0] = {'type': 'AGGREGATE', 'function': p[1], 'distinct': True, 'argument': p[4]}

    # 扩展expression以支持函数调用和CASE表达式
    def p_expression(self, p):
        """expression : expression PLUS expression
                    | expression MINUS expression
                    | expression MULTIPLY expression
                    | expression DIVIDE expression
                    | expression MODULO expression
                    | LPAREN expression RPAREN
                    | column_reference
                    | literal
                    | function_call
                    | case_expression"""
        if len(p) == 4:
            if p[1] == '(':
                p[0] = p[2]
            else:
                p[0] = {
                    'type': 'ARITHMETIC',
                    'operator': p[2],
                    'left': p[1],
                    'right': p[3]
                }
        else:
            p[0] = p[1]

    def p_function_call(self, p):
        """function_call : IDENTIFIER LPAREN argument_list RPAREN
                        | IDENTIFIER LPAREN RPAREN"""
        if len(p) == 5:
            p[0] = {'type': 'FUNCTION', 'name': p[1], 'arguments': p[3]}
        else:
            p[0] = {'type': 'FUNCTION', 'name': p[1], 'arguments': []}

    def p_argument_list(self, p):
        """argument_list : argument_list COMMA expression
                        | expression"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_case_expression(self, p):
        """case_expression : CASE when_clauses END
                        | CASE expression when_clauses END
                        | CASE when_clauses ELSE expression END
                        | CASE expression when_clauses ELSE expression END"""
        if len(p) == 4:
            p[0] = {'type': 'CASE', 'when_clauses': p[2]}
        elif len(p) == 5:
            if p[2] == 'WHEN':
                p[0] = {'type': 'CASE', 'when_clauses': p[2], 'else': p[3]}
            else:
                p[0] = {'type': 'CASE', 'base_expression': p[2], 'when_clauses': p[3]}
        else:
            p[0] = {'type': 'CASE', 'base_expression': p[2], 'when_clauses': p[3], 'else': p[5]}

    def p_when_clauses(self, p):
        """when_clauses : when_clauses when_clause
                        | when_clause"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[2]]

    def p_when_clause(self, p):
        """when_clause : WHEN condition THEN expression"""
        p[0] = {'when': p[2], 'then': p[4]}
    
    # DELETE 语句
    def p_delete_statement(self, p):
        """delete_statement : DELETE FROM IDENTIFIER
                            | DELETE FROM IDENTIFIER WHERE condition"""
        delete_stmt = {
            'type': 'DELETE',
            'table_name': p[3],
            'where_clause': None,
            'line': p.lineno(1)
        }
        
        if len(p) == 5:
            delete_stmt['where_clause'] = p[5]
        
        p[0] = delete_stmt
    
    # UPDATE 语句
    def p_update_statement(self, p):
        """update_statement : UPDATE IDENTIFIER SET assignment_list
                            | UPDATE IDENTIFIER SET assignment_list WHERE condition"""
        update_stmt = {
            'type': 'UPDATE',
            'table_name': p[2],
            'assignments': p[4],
            'where_clause': None,
            'line': p.lineno(1)
        }
        
        if len(p) == 7:
            update_stmt['where_clause'] = p[6]
        
        p[0] = update_stmt
    
    def p_assignment_list(self, p):
        """assignment_list : assignment_list COMMA assignment
                           | assignment"""
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        else:
            p[0] = [p[1]]
    
    def p_assignment(self, p):
        """assignment : IDENTIFIER EQUALS literal"""
        p[0] = {
            'column': p[1],
            'value': p[3]
        }
    
    # DROP TABLE 语句
    def p_drop_table_statement(self, p):
        """drop_table_statement : DROP TABLE IDENTIFIER"""
        p[0] = {
            'type': 'DROP_TABLE',
            'table_name': p[3],
            'line': p.lineno(1)
        }
    
    # WHERE 条件
    def p_condition(self, p):
        """condition : condition AND condition
                     | condition OR condition
                     | NOT condition
                     | expression comparison_operator expression
                     | expression BETWEEN expression AND expression
                     | LPAREN condition RPAREN"""
        if len(p) == 6 and p[2] == 'BETWEEN':
            # 处理 BETWEEN 条件
            p[0] = {
                'type': 'BETWEEN',
                'expression': p[1],
                'lower': p[3],
                'upper': p[5]
            }
        elif len(p) == 4:
            if p[1] == '(':
                p[0] = p[2]
            else:
                # 检查是否是逻辑操作符
                if p[2] in ['AND', 'OR']:
                    p[0] = {
                        'type': 'LOGICAL',
                        'operator': p[2],
                        'left': p[1],
                        'right': p[3]
                    }
                else:
                    # 比较操作符
                    p[0] = {
                        'type': 'COMPARISON',
                        'operator': p[2],
                        'left': p[1],
                        'right': p[3]
                    }
        elif len(p) == 3:
            p[0] = {
                'type': 'LOGICAL',
                'operator': 'NOT',
                'operand': p[2]
            }
        else:
            p[0] = {
                'type': 'COMPARISON',
                'operator': p[2],
                'left': p[1],
                'right': p[3]
            }
    
    def p_comparison_operator(self, p):
        """comparison_operator : EQUALS
                               | NOT_EQUALS
                               | LESS_THAN
                               | LESS_EQUAL
                               | GREATER_THAN
                               | GREATER_EQUAL"""
        p[0] = p[1]
    
    def p_column_reference(self, p):
        """column_reference : IDENTIFIER
                            | IDENTIFIER DOT IDENTIFIER"""
        if len(p) == 2:
            p[0] = {
                'type': 'COLUMN',
                'name': p[1]
            }
        else:
            p[0] = {
                'type': 'COLUMN',
                'table': p[1],
                'name': p[3]
            }
    
    # 错误处理
    def p_error(self, p):
        """处理语法错误"""
        if p:
            error_msg = f"语法错误: 在位置 {p.lexpos} 附近，遇到意外的token '{p.value}'"
            self.errors.append(error_msg)
        else:
            self.errors.append("语法错误: 意外的文件结束")
    
    def print_ast(self, ast: Dict[str, Any], indent: int = 0):
        """打印抽象语法树"""
        if not ast:
            return
        
        prefix = "  " * indent
        
        if ast['type'] == 'CREATE_TABLE':
            print(f"{prefix}CREATE_TABLE: {ast['table_name']}")
            print(f"{prefix}  Columns:")
            for col in ast['columns']:
                print(f"{prefix}    {col['name']}: {col['type']['type']}")
                if col.get('constraints'):
                    for constraint in col['constraints']:
                        print(f"{prefix}      {constraint['type']}")
        
        elif ast['type'] == 'INSERT':
            print(f"{prefix}INSERT INTO: {ast['table_name']}")
            if ast['columns']:
                print(f"{prefix}  Columns: {', '.join(ast['columns'])}")
            print(f"{prefix}  Values: {[v['value'] for v in ast['values']]}")
        
        elif ast['type'] == 'SELECT':
            print(f"{prefix}SELECT FROM: {ast['table_name']}")
            if ast['columns'] == '*':
                print(f"{prefix}  Columns: *")
            else:
                print(f"{prefix}  Columns: {', '.join(ast['columns'])}")
            if ast['where_clause']:
                print(f"{prefix}  WHERE:")
                self._print_condition(ast['where_clause'], indent + 2)
        
        elif ast['type'] == 'DELETE':
            print(f"{prefix}DELETE FROM: {ast['table_name']}")
            if ast['where_clause']:
                print(f"{prefix}  WHERE:")
                self._print_condition(ast['where_clause'], indent + 2)
        
        elif ast['type'] == 'UPDATE':
            print(f"{prefix}UPDATE: {ast['table_name']}")
            print(f"{prefix}  SET:")
            for assignment in ast['assignments']:
                print(f"{prefix}    {assignment['column']} = {assignment['value']['value']}")
            if ast['where_clause']:
                print(f"{prefix}  WHERE:")
                self._print_condition(ast['where_clause'], indent + 2)
        
        elif ast['type'] == 'DROP_TABLE':
            print(f"{prefix}DROP_TABLE: {ast['table_name']}")
    
    def _print_condition(self, condition: Dict[str, Any], indent: int):
        """打印WHERE条件"""
        prefix = "  " * indent
        
        if condition['type'] == 'COMPARISON':
            left = condition['left']['name'] if condition['left']['type'] == 'COLUMN' else str(condition['left']['value'])
            right = condition['right']['name'] if condition['right']['type'] == 'COLUMN' else str(condition['right']['value'])
            print(f"{prefix}{left} {condition['operator']} {right}")
        
        elif condition['type'] == 'LOGICAL':
            if condition['operator'] == 'NOT':
                print(f"{prefix}NOT")
                self._print_condition(condition['operand'], indent + 1)
            else:
                print(f"{prefix}{condition['operator']}")
                self._print_condition(condition['left'], indent + 1)
                self._print_condition(condition['right'], indent + 1)

def main():
    """测试语法分析器"""
    parser = ParserV3()
    
    # 测试SQL语句
    test_sqls = [
        "CREATE TABLE tst1 (id INT, name VARCHAR(50), age INT);",
        "INSERT INTO tst1 VALUES (1, 'Alice', 25);",
        "SELECT * FROM tst1 WHERE age > 20;",
        "DELETE FROM tst1 WHERE age > 20;"
    ]
    
    for sql in test_sqls:
        print(f"解析SQL: {sql}")
        print("-" * 60)
        
        ast = parser.parse(sql)
        if ast:
            parser.print_ast(ast)
        else:
            print("解析失败!")
            for error in parser.errors:
                print(f"错误: {error}")
        
        print("\n" + "="*80 + "\n")

if __name__ == "__main__":
    main()